package flex.cc.vehicle_svr.service.impl;

import com.alibaba.fastjson.JSONObject;
import flex.cc.PublicUtil;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.dto.vo.OrderMainVo;
import flex.cc.order.manage.enums.StatusEnum;
import flex.cc.order.manage.service.OrderMainService;
import flex.cc.order.manage.service.OrderTrackService;
import flex.cc.vehicle_svr.service.CancelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author wkangle
 * @className AsyncCancelService
 * @description 上游异步取消service
 * @time 2022-01-04 14:39:58
 */
@Service
public class AsyncCancelService {
    private static final Logger logger = LoggerFactory.getLogger(AsyncCancelService.class);

    @Autowired
    private OrderMainService orderMainService;
    @Autowired
    private OrderTrackService orderTrackService;
    @Autowired
    private CancelService cancelService;

    /**
     * @description 上游异步取消
     * @param requestBodyMap 取消接口参数
     * @param cancelUrl 请求URL
     * @param orderMainEntity 服务单实体
     * @param sourceName01 操作人
     * @return
     * @author wkangle
     * @time 2022-01-04 14:40:51
     * @exception/throws
    */
    @Async
    public Future<String> asyncCancelOrder(Map<String, Object> requestBodyMap, String cancelUrl, OrderMainEntity orderMainEntity, String sourceName01) {
        AtomicReference<Integer> counter = new AtomicReference<Integer>(0);
        Integer temp_code = 9999; // 请求下游取消接口返回的code码
        String message = "";
        String cancelRescueResult = "";
        while (counter.get() < 3) {
            cancelRescueResult = cancelService.cancelRescue(cancelUrl, requestBodyMap);
            logger.info("上游取消结果 ==> cancelRescueResult: " + cancelRescueResult);
            if (cancelRescueResult != null) {
                try {
                    JSONObject resultObject = JSONObject.parseObject(cancelRescueResult);
                    String resultCode = PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null;
                    logger.info("取消结果 ==> resultCode: " + resultCode);
                    message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;
                    logger.info("取消结果 ==> message: " + message);
                    temp_code = Integer.valueOf(resultCode);
                    if (PublicUtil.isNotEmpty(resultCode) && "9999".equals(resultCode)) {
                        counter.compareAndSet(counter.get(), counter.get()+1);
                    } else {
                        counter.getAndSet(5);
                    }
                } catch (Exception e) {
                    temp_code = 9998;
                    message = "下游返回值解析失败";
                    counter.getAndSet(5);
                }
            } else {
                counter.compareAndSet(counter.get(), counter.get()+1);
            }
        }

        if (cancelRescueResult != null) {
            if (temp_code == 0) {
                // 下游取消成功，更新车服平台服务单状态为服务取消
                // 2022-01-04 14:16:17 到店类服务需求取消优化：上游发起取消时不用调用上游取消通知接口，此处为了区分给服务单主表新增字段cancel_channel取消渠道：1-上游，2-下游，3-车服，4-C端
                // orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                orderMainEntity.setCancelChannel("1");
                orderMainEntity.setStatus("09");
                orderMainEntity.setUpdateTime(new Date());
                orderMainEntity.setUpdater(sourceName01);
                orderMainService.update(orderMainEntity);
                logger.info("取消备注：下游取消成功，更新车服平台服务单状态为服务取消，并记录救援轨迹.......");
                // 服务单轨迹表
                // 取消备注；服务取消；任务结束
                saveTrack(orderMainEntity.getOrderNo(),
                        "03",
                        "下游取消成功",
                        "09",
                        StatusEnum.getName("09"),
                        new Date(),
                        sourceName01);

            } else {
                // 下游取消失败，记录原因
                logger.info("取消备注：下游取消失败.......... " + message);
                // 救援轨迹；服务取消；任务结束
                saveTrack(orderMainEntity.getOrderNo(),
                        "03",
                        "下游取消失败：" + message,
                        "09",
                        StatusEnum.getName("09"),
                        new Date(),
                        sourceName01);

            }
            return new AsyncResult<>(cancelRescueResult);
        } else {
            // 下游取消失败，记录原因
            logger.info("取消备注：下游取消失败：取消接口请求异常");
            // 救援轨迹；服务取消；任务结束
            saveTrack(orderMainEntity.getOrderNo(),
                    "03",
                    "下游取消失败：取消接口请求异常",
                    "09",
                    StatusEnum.getName("09"),
                    new Date(),
                    sourceName01);
            return new AsyncResult<>("{\"resultCode\":\"1\",\"message\":\"取消失败，取消接口请求异常\"}");
        }
    }

    /**
     * @description 上游异步取消
     * @param requestBodyMap 取消接口参数
     * @param cancelUrl 请求URL
     * @param orderMainEntity 服务单
     * @param orderMain 服务单信息
     * @param sourceName01 操作人
     * @param remark 取消原因
     * @return
     * @author wkangle
     * @time 2022-01-04 14:40:51
     * @exception/throws
     */
    @Async
    public Future<String> asyncCancelInfo(Map<String, Object> requestBodyMap, String cancelUrl, OrderMainEntity orderMainEntity, OrderMainVo orderMain, String sourceName01, String remark) {
        AtomicReference<Integer> counter = new AtomicReference<Integer>(0);
        Integer temp_code = 9999; // 请求下游取消接口返回的code码
        String message = "";
        String cancelRescueResult = "";
        while (counter.get() < 3) {
            cancelRescueResult = cancelService.cancelRescue(cancelUrl, requestBodyMap);
            logger.info("客户取消结果 ==> cancelRescueResult: " + cancelRescueResult);
            if (cancelRescueResult != null) {
                try {
                    JSONObject resultObject = JSONObject.parseObject(cancelRescueResult);
                    String resultCode = PublicUtil.isNotEmpty(resultObject.get("resultCode")) ? resultObject.get("resultCode").toString() : null;
                    logger.info("客户取消结果 ==> resultCode: " + resultCode);
                    message = PublicUtil.isNotEmpty(resultObject.get("message")) ? resultObject.get("message").toString() : null;
                    logger.info("客户取消结果 ==> message: " + message);
                    temp_code = Integer.valueOf(resultCode);
                    if (PublicUtil.isNotEmpty(resultCode) && "9999".equals(resultCode)) {
                        counter.compareAndSet(counter.get(), counter.get()+1);
                    } else {
                        counter.getAndSet(5);
                    }
                } catch (Exception e) {
                    temp_code = 9998;
                    message = "下游返回值解析失败";
                    counter.getAndSet(5);
                }
            } else {
                counter.compareAndSet(counter.get(), counter.get()+1);
            }
        }

        if (cancelRescueResult != null) {
            if (temp_code == 0) {
                // 下游取消成功，更新车服平台服务单状态为服务取消
                //orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                // 2022-01-04 14:16:17 到店类服务需求取消优化：上游发起取消时不用调用上游取消通知接口，此处为了区分给服务单主表新增字段cancel_channel取消渠道：1-上游，2-下游，3-车服，4-C端
                // orderMainService.updateStatus(orderMainEntity.getDataId(), "09", new Date(), sourceName01);
                orderMainEntity.setCancelChannel("4");
                orderMainEntity.setStatus("09");
                orderMainEntity.setUpdateTime(new Date());
                orderMainEntity.setUpdater(sourceName01);
                orderMainService.update(orderMainEntity);
                logger.info("救援轨迹：客户取消成功，更新车服平台服务单状态为服务取消，并记录救援轨迹.......");
                // 服务单轨迹表
                // 取消备注；服务取消；任务结束
                saveTrack(orderMainEntity.getOrderNo(),"06","客户取消成功"+orderMain.getCancelReason().split(";")[1]+remark,"09",StatusEnum.getName("09"),new Date(),sourceName01);
            } else {
                // 客户取消失败，记录原因
                logger.info("救援轨迹：客户取消失败.......... " + message);
                // 救援轨迹；服务取消；任务结束
                saveTrack(orderMainEntity.getOrderNo(),"06","客户取消失败：" + message,"09",StatusEnum.getName("09"),new Date(),sourceName01);
            }
            return new AsyncResult<>(cancelRescueResult);
        } else {
            // 客户取消失败，记录原因
            logger.info("救援轨迹：客户取消失败：取消接口请求异常");
            // 救援轨迹；服务取消；任务结束
            saveTrack(orderMainEntity.getOrderNo(), "06", "客户取消失败：取消接口请求异常", "09", StatusEnum.getName("09"), new Date(),sourceName01);
            return new AsyncResult<>("{\"resultCode\":\"1\",\"message\":\"下游取消失败：取消接口请求异常\"}");
        }
    }
    /**
     * @param orderNo       服务单号
     * @param trackType     轨迹类型
     * @param trackDesc     轨迹描述
     * @param status        状态
     * @param serviceStatus 下游回传状态描述
     * @param currentDate   当前时间
     * @param sourceName01  操作人
     * @return
     * @description 根据条件保存轨迹
     * @author wkangle
     * @time 2021/10/09 0009 11:13
     * @exception/throws
     */
    private void saveTrack(String orderNo, String trackType, String trackDesc, String status, String serviceStatus, Date currentDate, String sourceName01) {
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setServiceStatus(serviceStatus);

        orderTrackEntity.setSynTime(PublicUtil.isNotEmpty(serviceStatus) ? currentDate : null); // 当serviceStatus不为空即该轨迹是“救援轨迹-任务结束”时，记操作时间为当前时间，用于展示在救援信息列表中，相当于状态回写接口报文中的操作时间。

        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(sourceName01);
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(sourceName01);
        orderTrackService.insert(orderTrackEntity);
    }


}
